package utils;

import java.util.ArrayList;

import figuras.PuntoVector;
import figuras.Segmento;

public class UtilesMalleado {
	
	/**
	 * Calcula los segmentos que representan una lista de puntos
	 * @param points ArrayList con los PuntoVector que representa la lista de puntos
	 * @return ArrayList con los segmentos que representan los puntos de entrada
	 */
	public static ArrayList<Segmento> puntosASegmentos(ArrayList<PuntoVector> points){
		ArrayList<Segmento> listaSegmentos = new ArrayList<Segmento>();
		PuntoVector s1 = points.get(0);
		for(int i=1;i<points.size();i++){
			PuntoVector s2 = points.get(i);
			Segmento s = new Segmento(s1, s2);
			listaSegmentos.add(s);
			s1=s2;
		}
		return listaSegmentos;
	}
	
	/**
	 * 
	 * @param points
	 * @param nPoints
	 * @param divisionesX
	 * @param suma
	 */
	public static void moldeadoLongitudinal(PuntoVector[] points, int divisionesX,int divisionesY, ArrayList<PuntoVector> suma){
		points[0].setZ(suma.get(0).getZ());
		for(int i = 1; i <suma.size();i++){
			double sumando = suma.get(i).getZ(); 
			for(int j=0; j<=divisionesX;j++){			
				points[(i*(divisionesX+1)-divisionesX + j)].setZ(points[(i*(divisionesX+1)-divisionesX + j)].getZ()+sumando);
			}
		}
		//points[points.length-1].setZ(suma.get(suma.size()-1).getZ());
	}
	
	/**
	 * 
	 * @param points
	 * @param nPoints
	 * @param divisionesX
	 * @param divisionesY
	 * @param suma
	 * @param index
	 * @param tipo
	 */
	public static void moldeadoTransversal(PuntoVector[] points,int nPoints,int divisionesX, int divisionesY,ArrayList<PuntoVector> suma, int index, int tipo, PuntoVector pFinalBSpline){
		System.out.println("index: "+ index);
		switch(tipo){
			case 0 : {
				//deformacion transversal de izq a dch
				System.out.println("Deformacion transversal tipo 0");
				//identificamos que linea es la que estamos deformando
				int linea = calculaLinea(index,divisionesX);
				System.out.println("linea "+linea);
				for(int i = 1; i <divisionesX;i++){
					points[index+i].setZ(points[index+i].getZ()+suma.get(i).getZ());
					//points[index+i].setZ(suma.get(i).getZ());
				}
				
				//variable para calcular el primer vertice de cada linea dentro del array de vertices de la malla
				int nDiv = index;
				
				//para cada linea anterior
				for(int i = linea-1; i > 0; i--){
					//para cada punto de la linea
					nDiv = nDiv -(divisionesX+1);
					//calculamos el decremento para cada linea
					double porcentaje = (double)i / linea;
					for(int j = 1; j <divisionesX;j++){
						//points[nDiv+j].setZ(suma.get(j).getZ()*porcentaje);
						points[nDiv+j].setZ(points[nDiv+j].getZ()+suma.get(j).getZ()*porcentaje);
					}					
					
				}
				nDiv = index;
				
				//para cada linea posterior
				for(int i = linea+1;i<divisionesY;i++){
					//para cada punto de la linea
					nDiv = nDiv +(divisionesX+1);
					//calculamos el decremento para cada linea
					double porcentaje = (double)( i - divisionesY)/(linea - divisionesY);
					for(int j = 1; j <divisionesX;j++){
						//points[nDiv+j].setZ(suma.get(j).getZ()*porcentaje);
						points[nDiv+j].setZ(points[nDiv+j].getZ()+suma.get(j).getZ()*porcentaje);
					}
				}
				break;
			}
			case 1 : {
				int nVertices = (divisionesX + 1);
				int verticesIzq = nVertices / 2;
				System.out.println("Deformacion transversal tipo 1");
				//deformacion transversal de izq a centro
				
				//identificamos que linea es la que estamos deformando
				int linea = calculaLinea(index,divisionesX);
				for(int i = 0; i <verticesIzq;i++){
					//points[index+i].setZ(suma.get(i).getZ());
					points[index+i].setZ(points[index+i].getZ()+suma.get(i).getZ());
				}
				
				//variable para calcular el primer vertice de cada linea dentro del array de vertices de la malla
				int nDiv = index;
				
				//para cada linea anterior
				for(int i = linea-1; i > 0; i--){
					//para cada punto de la linea
					nDiv = nDiv -(divisionesX+1);
					//calculamos el decremento para cada linea
					double porcentaje = (double)i / linea;
					for(int j = 0; j <verticesIzq;j++){
						//points[nDiv+j].setZ(suma.get(j).getZ()*porcentaje);
						points[nDiv+j].setZ(points[nDiv+j].getZ()+suma.get(j).getZ()*porcentaje);
					}					
					
				}
				nDiv = index;
				
				//para cada linea posterior
				for(int i = linea+1;i<divisionesY;i++){
					//para cada punto de la linea
					nDiv = nDiv +(divisionesX+1);
					//calculamos el decremento para cada linea
					double porcentaje = (double)( i - divisionesY)/(linea - divisionesY);
					for(int j = 0; j <verticesIzq;j++){
						//points[nDiv+j].setZ(suma.get(j).getZ()*porcentaje);
						points[nDiv+j].setZ(points[nDiv+j].getZ()+suma.get(j).getZ()*porcentaje);
					}
				}
				break;
			}
			case 2 : {
				System.out.println("Deformacion transversal tipo 2");
				//deformacion transversal de dch a centro
				int nVertices = (divisionesX + 1);
				int verticesIzq = nVertices / 2;
				int verticesDch = nVertices - verticesIzq -1;
				//identificamos que linea es la que estamos deformando
				int linea = calculaLinea((index - verticesIzq),divisionesX);
				for(int i = 0; i <verticesDch;i++){
					//points[index+i].setZ(suma.get(i).getZ());
					points[index+i].setZ(points[index+i].getZ()+suma.get(i).getZ());
				}
				
				//variable para calcular el primer vertice de cada linea dentro del array de vertices de la malla
				int nDiv = index;
				
				//para cada linea anterior
				for(int i = linea-1; i > 0; i--){
					//para cada punto de la linea
					nDiv = nDiv -(divisionesX+1);
					//calculamos el decremento para cada linea
					double porcentaje = (double)i / linea;
					for(int j = 0; j <verticesDch;j++){
						//points[nDiv+j].setZ(suma.get(j).getZ()*porcentaje);	
						points[nDiv+j].setZ(points[nDiv+j].getZ()+suma.get(j).getZ()*porcentaje);
					}					
					
				}
				nDiv = index;
				
				//para cada linea posterior
				for(int i = linea+1;i<divisionesY;i++){
					//para cada punto de la linea
					nDiv = nDiv +(divisionesX+1);
					//calculamos el decremento para cada linea
					double porcentaje = (double)( i - divisionesY)/(linea - divisionesY);
					for(int j = 0; j <verticesDch;j++){
						//points[nDiv+j].setZ(suma.get(j).getZ()*porcentaje);	
						points[nDiv+j].setZ(points[nDiv+j].getZ()+suma.get(j).getZ()*porcentaje);
					}
				}
				break;
			}
			case 3 : {
				//esta deformacion es del centro de la vena a la izquierda
				System.out.println("Deformacion transversal tipo 3");				
				//el indice indica el centro de la vena de esa linea;
				int nDiv = index - (divisionesX/2);
				int linea = calculaLinea(nDiv,divisionesX);
				System.out.println("index "+index);
				System.out.println("nDiv "+nDiv);

				System.out.println("linea "+linea);
				double factorSuma = pFinalBSpline.getX() - points[nDiv].getX();
				points[nDiv].setX(pFinalBSpline.getX());				
				
				
				int verticesIzq = divisionesX /2;
				double inicio = points[nDiv].getX();
				double distancia = inicio-points[index].getX();
				double inc = distancia / (double) verticesIzq;
				for(int i = 1; i< divisionesX/2; i++){
					points[nDiv+i].setX(inicio-i*inc);
				}
				
				//para cada linea anterior
				for(int i = linea-1; i > 0; i--){
					//para cada punto de la linea
					nDiv = nDiv -(divisionesX+1);
					//calculamos el decremento para cada linea
					double porcentaje = (double)i / linea;
					points[nDiv].setX(points[nDiv].getX() +factorSuma*porcentaje);
					inicio = points[nDiv].getX();
					distancia = inicio-points[nDiv+verticesIzq].getX();
					inc = distancia / (double) verticesIzq;
					for(int j = 1; j< verticesIzq; j++){
						points[nDiv+j].setX(inicio-j*inc);
					}
					
					
				}
				
				nDiv = index - (divisionesX/2);				
				//para cada linea posterior
				for(int i = linea+1;i<divisionesY;i++){
					//para cada punto de la linea
					nDiv = nDiv +(divisionesX+1);
					//calculamos el decremento para cada linea
					double porcentaje = (double)( i - divisionesY)/(linea - divisionesY);
					points[nDiv].setX(points[nDiv].getX() +factorSuma*porcentaje);
					inicio = points[nDiv].getX();
					distancia = inicio-points[nDiv+verticesIzq].getX();
					inc = distancia / (double) verticesIzq;
					for(int j = 1; j< verticesIzq; j++){
						points[nDiv+j].setX(inicio-j*inc);
					}
				}
				break;
			}
			case 4 : {
				//esta deformacion es del centro de la vena a la derecha
				System.out.println("Deformacion transversal tipo 4");				
				//el indice indica el centro de la vena de esa linea;
				int nDiv = index - (divisionesX/2) + divisionesX;
				System.out.println("index "+index);
				System.out.println("nDiv "+nDiv);
				//int linea = (nDiv) % divisionesX;	
				int linea = calculaLinea(nDiv,divisionesX);
				System.out.println("linea "+linea);
				double factorSuma = pFinalBSpline.getX() - points[nDiv].getX();
				points[nDiv].setX(pFinalBSpline.getX());
			
				int nVertices = (divisionesX + 1);
				int verticesIzq = nVertices / 2;
				int verticesDch = nVertices - verticesIzq -1;
				double inicio = points[nDiv].getX();
				double distancia = inicio-points[index].getX();
				double inc = distancia / (double) verticesDch;
				for(int i = 1; i< divisionesX/2; i++){
					points[nDiv-i].setX(inicio-i*inc);
				}
				
				
				//para cada linea anterior
				for(int i = linea-1; i > 0; i--){
					//para cada punto de la linea
					nDiv = nDiv -(divisionesX+1);
					//calculamos el decremento para cada linea
					double porcentaje = (double)i / linea;					
					points[nDiv].setX(points[nDiv].getX() +factorSuma*porcentaje);
					inicio = points[nDiv].getX();
					distancia = inicio-points[nDiv-verticesDch].getX();
					inc = distancia / (double) verticesDch;
					for(int j = 1; j< verticesDch; j++){
						points[nDiv-j].setX(inicio-j*inc);
					}
				}
				
				nDiv = index - (divisionesX/2) + divisionesX;		
				//para cada linea posterior
				System.out.println(linea);
				for(int i = linea+1;i<divisionesY;i++){
					//para cada punto de la linea
					nDiv = nDiv +(divisionesX+1);
					//calculamos el decremento para cada linea
					double porcentaje = (double)( i - divisionesY)/(linea - divisionesY);
					points[nDiv].setX(points[nDiv].getX() +factorSuma*porcentaje);
					inicio = points[nDiv].getX();
					distancia = inicio-points[nDiv-verticesDch].getX();
					inc = distancia / (double) verticesDch;
					for(int j = 1; j< verticesDch-1; j++){
						points[nDiv-j].setX(inicio-j*inc);
					}
				}
				break;
			}
			default : {
				System.out.println("Deformacion transversal incorrecta");
			}
		}
	}
	
	public static int calculaLinea(int index, int divX){
		int i = 1;
		while(index > i*(divX+1))
			i++;
		return i;
	}
	
}
